﻿// 下面是一个 模拟银行卡余额存取操作的多线程互斥锁示例，用于说明当多个线程同时对共享资源（如余额）进行读写时必须加锁，否则可能会出现数据错误的问题：
// 模拟多人同时存钱和取钱：使用 std::mutex 保证线程安全
// 模拟多人同时存钱和取钱：使用 std::mutex 保证线程安全
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <Windows.h>  // Windows 平台专用

int balance = 1000;         // 银行账户初始余额
std::mutex mtx;             // 互斥锁，用于保护余额的访问

// 模拟取钱操作
void withdraw(int amount, const std::string& name) {
    for (int i = 0; i < 5; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟处理延迟
        std::lock_guard<std::mutex> lock(mtx);  // 自动加锁和解锁
        if (balance >= amount) {
            balance -= amount;
            std::cout << name << " 成功取出 " << amount << "，剩余余额: " << balance << std::endl;
        } else {
            std::cout << name << " 取款失败，余额不足！当前余额: " << balance << std::endl;
        }
    }
}

// 模拟存钱操作
void deposit(int amount, const std::string& name) {
    for (int i = 0; i < 5; ++i) {
        std::this_thread::sleep_for(std::chrono::milliseconds(150)); // 模拟处理延迟
        std::lock_guard<std::mutex> lock(mtx);  // 自动加锁和解锁
        balance += amount;
        std::cout << name << " 存入 " << amount << "，当前余额: " << balance << std::endl;
    }
}

int main() {
    // 设置控制台输出为 UTF-8 编码，防止中文乱码（Windows 特有）
    SetConsoleOutputCP(65001);
    std::ios::sync_with_stdio(false); // 关闭 C 和 C++ 输出同步，加速输出

    std::thread t1(withdraw, 300, "张三");  // 张三每次取300
    std::thread t2(deposit, 500, "李四");   // 李四每次存500
    std::thread t3(withdraw, 400, "王五");  // 王五每次取400

    t1.join();
    t2.join();
    t3.join();

    std::cout << "最终余额: " << balance << std::endl;
    return 0;
}
